package team8.fitdroid;


import java.util.LinkedList;
import java.util.StringTokenizer;
import java.lang.Math;

import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.TimeChart;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import team8.database.databaseconnector;
import team8.helpers.numberformat;
import team8.helpers.timehelper;
import team8.helpers.user;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.format.Time;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

public class runmanager extends Activity implements LocationListener {
	//new button for launching exercise
	private Button startexercisebutton;
	
	
	String DEFAULT_GRAPHTIME = "0:05:00";
	int updatetimes = 4;
	int diffheight = 50;
	
	long initialtime;
	
	long currenttime;
	long runmillitime;
    double currentxmin;
    double currentxmax;
    double currentymin;
    double currentymax;
    
	private String latitude;
	private String longitude;
	private String altitude;

	private LocationManager locMgrGPS = null;
	private double currentdistance = 0;
	private double currentcalorie=0;
	private Location oldlocation = null;

	private ProgressBar timepro;
	private int timeprogressstatus = 0;
	private Handler timeHandler = new Handler();
	private Chronometer timechr;

	private TextView distancetext;
	private ProgressBar distancepro;
	private int distanceprogressstatus = 0;
	//private Handler distanceHandler = new Handler();

	private TextView calorietext;
	private ProgressBar caloriepro;
	private int calorieprogressstatus = 0;
	//private Handler calorieHandler = new Handler();
	
	//related to the LineChart
	private TextView altitudetext;
	private TimeChart chart;
	private XYMultipleSeriesDataset mDataset = new XYMultipleSeriesDataset();
	private XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();
	private XYSeries mSpeedSeries;
	private XYSeries mAltitudeSeries;
	private XYSeriesRenderer mCurrentRenderer;
	private GraphicalView mChartView;
	
	

	private TextView speedtext;

	private static String maxdistance;
	private static String maxspeed;
	private static String maxcalorie;
	private static String maxtime;
	
	private databaseconnector database;
	private int trackid;
	
	private user runner;
	private timehelper time= new timehelper();
	private double runnerweight=70; // Standart value 70kg
	
	private LinkedList<Location> gpspositions = new LinkedList<Location>();
	
    // new Button for exercise trainer
	
    private OnClickListener startexercisebuttonListener = new OnClickListener() {
        public void onClick(View v) {
          // do something when the button is clicked
        	
        	Intent i = new Intent(runmanager.this, ExerciseTrainer.class);
        	//runmanager.init(distanceedi.getText().toString(), calorieedit.getText().toString(), speededit.getText().toString(), timeedit.getText().toString());
        	ExerciseTrainer.init(runmanager.this);
        	startActivity(i);
            onPause();
            onStop();
            
        }
    };
public void restart() {
	onRestart();
	onStart();
	onResume();
}
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.runmanager);
		Log.d("hallo","wie geht es");
		//added for exercise 
		startexercisebutton= (Button)findViewById(R.id.startexercisebutton);
        startexercisebutton.setOnClickListener(startexercisebuttonListener);

		locMgrGPS = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
		// attr 2 = every x ms look for an update
		// attr 3 = every x meters position changing update
		locMgrGPS.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1, 1,this);
		
		database= new databaseconnector(this);
		trackid =database.newtrack(database.getWritableDatabase());
		
		timepro = (ProgressBar) findViewById(R.id.timeprogressbar);
		timechr = (Chronometer) findViewById(R.id.chronometer);
		
		runner= new user(database);

		distancetext = (TextView) findViewById(R.id.distancetext);
		distancepro = (ProgressBar) findViewById(R.id.distanceprogressbar);

		calorietext = (TextView) findViewById(R.id.calorietext);
		caloriepro = (ProgressBar) findViewById(R.id.calorieprogressbar);

		speedtext = (TextView) findViewById(R.id.speedtext);
		
		altitudetext = (TextView) findViewById(R.id.altitudetext);
		
		graphsetup();

		this.start();
		
	}
private void graphsetup() {
	 String seriesTitle = "Speed" ;
	 String seriesTitle2 = "Altitude";
       // XYSeries series = new XYSeries(seriesTitle);
       // XYSeries series2 = new XYSeries(seriesTitle2);
	    mSpeedSeries = new XYSeries(seriesTitle);
        mAltitudeSeries = new XYSeries(seriesTitle2);
	    mDataset.addSeries(mSpeedSeries);
        mDataset.addSeries(mAltitudeSeries);
             
        XYSeriesRenderer renderer = new XYSeriesRenderer();
        XYSeriesRenderer renderer2 = new XYSeriesRenderer();
        
        int c = renderer.getColor();
        renderer2.setColor(c - 500);
        mRenderer.addSeriesRenderer(renderer);
        mRenderer.addSeriesRenderer(renderer2);
        mCurrentRenderer = renderer;

        LinearLayout layout = (LinearLayout) findViewById(R.id.chart);
	      mChartView = ChartFactory.getLineChartView(this, mDataset, mRenderer);
	      layout.addView(mChartView, new LayoutParams(LayoutParams.FILL_PARENT,
	          LayoutParams.FILL_PARENT));  
}

	@Override
	public void onLocationChanged(Location arg0) {
		// TODO Auto-generated method stub
		
		this.latitude = String.valueOf(arg0.getLatitude());
		this.longitude = String.valueOf(arg0.getLongitude());
		this.altitude = String.valueOf(arg0.getAltitude());
		
		// update TextView
		updateSpeedandDistance(arg0);
		updatecalorie();
		updatetimes++;; 
		if(updatetimes == 5){
		updategraph(arg0);
		updatetimes = 0;
		}
		
		// insert new position into database
		oldlocation = arg0;
		//gpspositions.add(arg0);
		

	}

	@Override
	public void onProviderDisabled(String provider) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onProviderEnabled(String provider) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub

	}

	public void start() {
		if (maxdistance.equals("0"))
			this.distancepro.setVisibility(View.INVISIBLE);

		if (maxcalorie.equals("0"))
			this.caloriepro.setVisibility(View.INVISIBLE);

		if (maxtime.equals("00:00:00"))
			this.timepro.setVisibility(View.INVISIBLE);
		
		
		timechr.start();
		
		final boolean timevis = (timepro.VISIBLE==View.VISIBLE);
		final boolean distancevis = (distancepro.VISIBLE==View.VISIBLE);
		final boolean calorievis = (caloriepro.VISIBLE==View.VISIBLE);
		
		if (timevis || distancevis || calorievis)
		{
			new Thread(new Runnable() {
	            public void run() {
	            	
	                while (timeprogressstatus < 100 || distanceprogressstatus < 100 || calorieprogressstatus < 100) {
	                	if (timeprogressstatus < 100 && timevis)
	                		timeprogressstatus = calctimeprogress();
	                	if (distanceprogressstatus < 100 && distancevis)
	                		distanceprogressstatus = calcdistanceprogress();
	                	if (calorieprogressstatus < 100 && calorievis)
	                		calorieprogressstatus = calccalorieprogress();
	                    // Update the progress bar
	                	timeHandler.post(new Runnable() {
	                        public void run() {
	                        	if (timevis)
	                        		timepro.setProgress(timeprogressstatus);
	                        	if (distancevis)
	                        		distancepro.setProgress(distanceprogressstatus);
	                        	if (calorievis)
	                        		caloriepro.setProgress(calorieprogressstatus);
	                        	//Log.d("Bla",String.valueOf(timeprogressstatus));
	                        }
	                    });
	                }
	            }
	        }).start();
		}
		
		
		
		//timeprogressbar
		/*if (timepro.VISIBLE==View.VISIBLE)
		{
			//Log.d("Hallo",String.valueOf(timepro.VISIBLE)+"   "+String.valueOf(View.VISIBLE));
			new Thread(new Runnable() {
	            public void run() {
	            	
	                while (timeprogressstatus < 100) {
	                	timeprogressstatus = calctimeprogress();
	                	
	                    // Update the progress bar
	                	timeHandler.post(new Runnable() {
	                        public void run() {
	                        	timepro.setProgress(timeprogressstatus);
	                        	//Log.d("Bla",String.valueOf(timeprogressstatus));
	                        }
	                    });
	                }
	            }
	        }).start();
		}
		
		//distanceprogressbar
		if (distancepro.VISIBLE==View.VISIBLE)
		{
			new Thread(new Runnable() {
	            public void run() {
	                while (distanceprogressstatus < 100) {
	                	distanceprogressstatus = calcdistanceprogress();
	                	
	                    // Update the progress bar
	                	distanceHandler.post(new Runnable() {
	                        public void run() {
	                        	distancepro.setProgress(distanceprogressstatus);
	                        	//Log.d("Bla",String.valueOf(timeprogressstatus));
	                        }
	                    });
	                }
	            }
	        }).start();
		}
		//calorieprogressbar
		if (caloriepro.VISIBLE==View.VISIBLE)
		{
			new Thread(new Runnable() {
	            public void run() {
	                while (calorieprogressstatus < 100) {
	                	calorieprogressstatus = calccalorieprogress();
	                	
	                    // Update the progress bar
	                	calorieHandler.post(new Runnable() {
	                        public void run() {
	                        	caloriepro.setProgress(calorieprogressstatus);
	                        	//Log.d("Bla",String.valueOf(timeprogressstatus));
	                        }
	                    });
	                }
	            }
	        }).start();
		}*/

		// if user exists get his weight
		
		LinkedList<String> data = runner.getuserdata();
		if (data.size()>0)
		{
			if (Integer.valueOf(data.get(2))!=0)
				runnerweight = Double.valueOf(data.get(2));			
		}
		
	}
	
	public static void init (String distance, String calories, String speed, String time) {
		maxdistance = distance;
		maxcalorie = calories;
		maxtime = time;
		maxspeed=speed;

	}
	
	private void updategraph(Location newlocation){
		if (oldlocation == null) {
			
			currentymin = newlocation.getAltitude() - diffheight;
			currentymax = newlocation.getAltitude() + diffheight;
			
			mRenderer.setYAxisMin(currentymin);
			mRenderer.setYAxisMax(currentymax);
			initialtime= System.currentTimeMillis();
			
			
			if (maxtime.equals("00:00:00")) {
				long factor=60*60;
				StringTokenizer tokenizer = new StringTokenizer (DEFAULT_GRAPHTIME, ":");
				long calctime=0;
				while (tokenizer.hasMoreTokens())
				{
					calctime += Long.valueOf(tokenizer.nextToken().trim())*factor;
					factor /= 60;
				}
				calctime = calctime * 1000;
				runmillitime = calctime;
				mRenderer.setXAxisMin(0);
				mRenderer.setXAxisMax(calctime);
					
			}else {
				long factor=60*60;
				StringTokenizer tokenizer = new StringTokenizer (maxtime, ":");
				long calctime=0;
				while (tokenizer.hasMoreTokens())
				{
					calctime += Long.valueOf(tokenizer.nextToken().trim())*factor;
					factor /= 60;
				}
				calctime = calctime * 1000;
				
				runmillitime = calctime;
				mRenderer.setXAxisMin(0);
				mRenderer.setXAxisMax(calctime);
			}
			altitudetext.setText("Altitude: "+ newlocation.getAltitude());
			mSpeedSeries.add(0,currentymin + newlocation.getSpeed());
			mAltitudeSeries.add(0, newlocation.getAltitude());
			mChartView.repaint();
			
			
		} else{
			
			currenttime =System.currentTimeMillis() - initialtime;
			if (maxtime.equals("00:00:00")) {
		    if (currenttime > runmillitime){
		    	runmillitime = runmillitime *2; 
		    	mRenderer.setXAxisMax(runmillitime);
			}
		    if (newlocation.getAltitude()> currentymax) {
		    	currentymax = currentymax + 50;
		    	//java.lang.Math.abs(currentymax);
		    	mRenderer.setYAxisMax(currentymax);
		    }else
		    if(newlocation.getAltitude()< currentymin){
		    	currentymin = currentymin - 50; 
		    }
			}
			altitudetext.setText("Altitude: "+ newlocation.getAltitude());
			mAltitudeSeries.add(currenttime, newlocation.getAltitude());
			mSpeedSeries.add(currenttime, currentymin + newlocation.getSpeed());
			
			mChartView.repaint();
		};
	}

	private void updateSpeedandDistance(Location newlocation) {
		// Update Distance in the TextView
		if (oldlocation == null) {
			distancetext.setText("Distance : 0 km");
		} 
		else 
		{
			currentdistance += numberformat.round2commas((oldlocation.distanceTo(newlocation) / 1000) );
			distancetext.setText("Distance : " + numberformat.round2commas(currentdistance) + " km");
		}

		// Update Speed in the TextView
		speedtext.setText("Speed : " + numberformat.round2commas(newlocation.getSpeed() * (3.6))+ " km/h");
	}
	
	private void updatecalorie ()
	{
			// I don't know if this formula is right
			/*double minutes =time.converttimeminutes(timechr.getText().toString());
	
			double speed = (currentdistance/(minutes/60));
			
	
			currentcalorie= Math.floor(((0.0009*(speed*speed))- (0.0065*speed) + 0.1408)*runnerweight*minutes*100)/100.0;
			*/
			currentcalorie = runnerweight*currentdistance;
			calorietext.setText("Calories : "+currentcalorie+" kCal");
	}

	
	private int calctimeprogress()
	{

		int currenttime = time.converttimeseconds(timechr.getText().toString()); 
		
		StringTokenizer tokenizer = new StringTokenizer (maxtime, ":");
		int calctime=0;
		int factor=60*60;
		
		while (tokenizer.hasMoreTokens())
		{
			calctime += Integer.valueOf(tokenizer.nextToken().trim())*factor;
			factor /= 60;
		}
		//Log.d("current",String.valueOf(currenttime));
		//Log.d("calc",String.valueOf((((currenttime*100)/calctime))));
		if (calctime>0)
			return ((currenttime*100)/calctime);
		else
			return 0;
	}
	
	private int calcdistanceprogress()
	{		
		String s= distancetext.getText().toString();
		//Log.d("!!!!!!", s);
		s= s.substring((s.lastIndexOf(':')+2),(s.length()-3));
		//Log.d("distancetext", "|"+s+"|");
		//Log.d("max", maxdistance);
		double currdistance= Double.valueOf(s.trim());
		double calcdistance = Double.valueOf(maxdistance.trim());
		
		 //Log.d ("test", String.valueOf((int)Math.round((currdistance*100)/calcdistance)));
		return (int)Math.round((currdistance*100)/calcdistance);
	}
	
	private int calccalorieprogress()
	{		
		String s= calorietext.getText().toString();
		//Log.d("!!!!!!", s);
		s= s.substring((s.lastIndexOf(':')+2),(s.length()-4));
		//Log.d("distancetext", "|"+s+"|");
		//Log.d("max", maxdistance);
		double currentcalorie= Double.valueOf(s.trim());
		double calccalorie = Double.valueOf(maxcalorie.trim());
		
		 //Log.d ("test", String.valueOf((int)Math.round((currentcalorie*100)/calccalorie)));
		return (int)Math.round((currentcalorie*100)/calccalorie);
	}
	
	/*@Override
	  public void onPause() {	  
		runner.storeuserdata(null, currentdistance, 0, 0, timechr.getText().toString());
		  super.onPause();
		  
	  }*/
	@Override
    public void onDestroy()
	{
		
		Log.d("Uha ","Destroy!!!!!!!!!!!");
		transfertodatabase();
		runner.storeuserdata(null, currentdistance, 0, 0, timechr.getText().toString());
		gpspositions.clear();
		database.close();
		super.onDestroy();
	}
	
	/*@Override
	public void onSaveInstanceState(Bundle savedInstanceState) {
		//runner.storeuserdata(null, currentdistance, 0, 0, timechr.getText().toString());
		//Log.d("Uha ","!!!!!!!!!!!");
		//transfertodatabase();
		//gpspositions.clear();
		super.onSaveInstanceState(savedInstanceState);	
	}*/
	
	
	private void transfertodatabase()
	{
		for(int i=0; i<gpspositions.size();i++)
		{
			database.insertnewgpsposition(database.getWritableDatabase(), gpspositions.get(i), trackid);
		}
	}
}

